let mediaRecorder;
let audioChunks = [];
let recordingTimeout;
const MAX_RECORDING_TIME = 30000; // 30秒

// API基础URL
const API_BASE_URL = 'http://localhost:8080/api';

const recordButton = document.getElementById('recordButton');
const resultDiv = document.getElementById('result');
const loadingDiv = document.getElementById('loading');
const statusIndicator = document.querySelector('.status-indicator');

// 将音频数据转换为指定采样率
async function convertToWav(audioData, targetSampleRate = 16000) {
    // 创建离线音频上下文
    const audioContext = new (window.AudioContext || window.webkitAudioContext)();
    
    // 从音频数据创建音频缓冲区
    const audioBuffer = await audioContext.decodeAudioData(await audioData.arrayBuffer());
    
    // 创建指定采样率的离线音频上下文
    const offlineCtx = new OfflineAudioContext(
        1, // 单声道
        audioBuffer.duration * targetSampleRate,
        targetSampleRate
    );
    
    // 创建音频源
    const source = offlineCtx.createBufferSource();
    source.buffer = audioBuffer;
    source.connect(offlineCtx.destination);
    source.start();
    
    // 渲染音频
    const renderedBuffer = await offlineCtx.startRendering();
    
    // 将音频缓冲区转换为WAV格式
    const wavData = audioBufferToWav(renderedBuffer);
    return new Blob([wavData], { type: 'audio/wav' });
}

// 将AudioBuffer转换为WAV格式
function audioBufferToWav(buffer) {
    const numChannels = 1; // 单声道
    const sampleRate = buffer.sampleRate;
    const format = 1; // PCM格式
    const bitDepth = 16; // 16位
    
    const channelData = buffer.getChannelData(0);
    const samples = new Int16Array(channelData.length);
    
    // 将浮点音频数据转换为16位整数
    for (let i = 0; i < channelData.length; i++) {
        const s = Math.max(-1, Math.min(1, channelData[i]));
        samples[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;
    }
    
    // 创建WAV文件头
    const wavHeader = new ArrayBuffer(44);
    const view = new DataView(wavHeader);
    
    // RIFF标识符
    writeString(view, 0, 'RIFF');
    view.setUint32(4, 36 + samples.length * 2, true);
    writeString(view, 8, 'WAVE');
    
    // 格式块
    writeString(view, 12, 'fmt ');
    view.setUint32(16, 16, true); // 块大小
    view.setUint16(20, format, true); // 音频格式
    view.setUint16(22, numChannels, true); // 声道数
    view.setUint32(24, sampleRate, true); // 采样率
    view.setUint32(28, sampleRate * 2, true); // 字节率
    view.setUint16(32, numChannels * 2, true); // 块对齐
    view.setUint16(34, bitDepth, true); // 位深度
    
    // 数据块
    writeString(view, 36, 'data');
    view.setUint32(40, samples.length * 2, true);
    
    // 合并文件头和音频数据
    const blob = new Blob([wavHeader, samples.buffer], { type: 'audio/wav' });
    return blob;
}

// 写入字符串到DataView
function writeString(view, offset, string) {
    for (let i = 0; i < string.length; i++) {
        view.setUint8(offset + i, string.charCodeAt(i));
    }
}

// 初始化录音功能
async function initializeRecording() {
    try {
        const stream = await navigator.mediaDevices.getUserMedia({
            audio: {
                channelCount: 1,
                sampleRate: 16000,
                sampleSize: 16,
                volume: 1
            }
        });
        
        mediaRecorder = new MediaRecorder(stream, {
            mimeType: 'audio/webm;codecs=opus'
        });

        mediaRecorder.ondataavailable = (event) => {
            audioChunks.push(event.data);
        };

        mediaRecorder.onstop = async () => {
            const audioBlob = new Blob(audioChunks, { type: 'audio/webm' });
            // 转换为16000Hz的WAV格式
            const wavBlob = await convertToWav(audioBlob);
            await sendAudioToServer(wavBlob);
        };

        // 麦克风权限获取成功
        statusIndicator.style.backgroundColor = '#22c55e';
        statusIndicator.title = '麦克风已就绪';
    } catch (err) {
        console.error('Error accessing microphone:', err);
        statusIndicator.style.backgroundColor = '#ef4444';
        statusIndicator.title = '无法访问麦克风';
        showError('无法访问麦克风，请确保已授予权限');
    }
}

// 发送音频到服务器
async function sendAudioToServer(audioBlob) {
    loadingDiv.classList.add('active');
    const formData = new FormData();
    formData.append('audio', audioBlob);

    try {
        await fetch(`${API_BASE_URL}/audio/transcribe`, {
            method: 'POST',
            body: formData
        });
    } catch (err) {
        console.error('Error sending audio:', err);
        loadingDiv.classList.remove('active');
        showError('发送音频失败，请重试');
    }
}

// 显示错误信息
function showError(message) {
    const errorDiv = document.createElement('div');
    errorDiv.style.cssText = `
        position: fixed;
        top: 20px;
        left: 50%;
        transform: translateX(-50%);
        background: #fee2e2;
        color: #dc2626;
        padding: 12px 24px;
        border-radius: 8px;
        box-shadow: 0 4px 12px rgba(220, 38, 38, 0.1);
        z-index: 1000;
        animation: slideDown 0.3s ease;
    `;
    errorDiv.textContent = message;
    document.body.appendChild(errorDiv);

    setTimeout(() => {
        errorDiv.style.animation = 'slideUp 0.3s ease';
        setTimeout(() => errorDiv.remove(), 300);
    }, 3000);
}

// 创建并触发链接点击
function openUrlSafely(url) {
    // 创建一个临时的a标签
    const link = document.createElement('a');
    link.href = url;
    link.target = '_blank';
    link.rel = 'noopener noreferrer';
    link.style.display = 'none';
    document.body.appendChild(link);
    
    // 模拟点击
    link.click();
    
    // 清理DOM
    setTimeout(() => {
        document.body.removeChild(link);
    }, 100);
}

// 设置Server-Sent Events监听
function setupSSE() {
    const eventSource = new EventSource(`${API_BASE_URL}/audio/stream`);
    
    eventSource.onmessage = (event) => {
        loadingDiv.classList.remove('active');
        try {
            // 尝试解析JSON
            const data = JSON.parse(event.data);
            
            // 如果是包含action和url的JSON对象
            if (data.intent = "openUrl" && data.result) {
                openUrlSafely(data.result);
            } else if (data.action === 'showText' && data.result) {
                // 显示转写的文本
                resultDiv.textContent = data.text;
            } else if (data.action === 'error') {
                // 显示错误信息
                showError(data.message || '处理过程中发生错误');
            } else {
                // 如果是其他类型的JSON，显示其内容
                resultDiv.textContent = JSON.stringify(data, null, 2);
            }
        } catch (e) {
            // 如果不是JSON，按普通文本显示
            resultDiv.textContent = event.data;
        }
        resultDiv.style.animation = 'fadeIn 0.5s ease';
    };

    eventSource.onerror = (error) => {
        console.error('SSE Error:', error);
        loadingDiv.classList.remove('active');
        eventSource.close();
        showError('与服务器的连接已断开，请刷新页面重试');
    };
}

// 添加动画样式
const style = document.createElement('style');
style.textContent = `
    @keyframes slideDown {
        from { transform: translate(-50%, -100%); opacity: 0; }
        to { transform: translate(-50%, 0); opacity: 1; }
    }
    @keyframes slideUp {
        from { transform: translate(-50%, 0); opacity: 1; }
        to { transform: translate(-50%, -100%); opacity: 0; }
    }
    @keyframes fadeIn {
        from { opacity: 0; }
        to { opacity: 1; }
    }
`;
document.head.appendChild(style);

// 初始化页面
document.addEventListener('DOMContentLoaded', () => {
    initializeRecording();
    setupSSE();

    // 按住开始录音
    recordButton.addEventListener('mousedown', () => {
        audioChunks = [];
        mediaRecorder.start();
        recordButton.innerHTML = '录音中';
        recordButton.style.animation = 'pulse 2s infinite';
        
        // 设置30秒后自动停止
        recordingTimeout = setTimeout(() => {
            if (mediaRecorder.state === 'recording') {
                mediaRecorder.stop();
                recordButton.innerHTML = '🎤';
                recordButton.style.animation = '';
            }
        }, MAX_RECORDING_TIME);
    });

    // 松开结束录音
    recordButton.addEventListener('mouseup', () => {
        if (mediaRecorder.state === 'recording') {
            clearTimeout(recordingTimeout);
            mediaRecorder.stop();
            recordButton.innerHTML = '🎤';
            recordButton.style.animation = '';
        }
    });

    // 如果鼠标移出按钮，也要停止录音
    recordButton.addEventListener('mouseleave', () => {
        if (mediaRecorder.state === 'recording') {
            clearTimeout(recordingTimeout);
            mediaRecorder.stop();
            recordButton.innerHTML = '🎤';
            recordButton.style.animation = '';
        }
    });

    // 初始化按钮文本
    recordButton.innerHTML = '🎤';
}); 
